/**
 * 全站路由配置
 *
 * 建议:
 * 1. 代码中路由统一使用name属性跳转(不使用path属性)
 */
import Vue from 'vue'; // 导入Vue核心库
import Router from 'vue-router'; // 导入vue-router库
import http from '@/utils/httpRequest'; // 导入HTTP请求工具
import { isURL } from '@/utils/validate'; // 导入验证函数，用于检查URL格式
import { clearLoginInfo } from '@/utils'; // 导入清除登录信息的函数

Vue.use(Router); // 安装vue-router插件

// 定义导入组件的方法，根据环境变量选择是否使用懒加载
const _import = require('./import-' + process.env.NODE_ENV);

// 定义全局路由，即不需要嵌套到任何布局中的独立页面
const globalRoutes = [
  { path: '/404', component: _import('common/404'), name: '404', meta: { title: '404未找到' } }, // 404错误页面
  { path: '/login', component: _import('common/login'), name: 'login', meta: { title: '登录' } } // 登录页面
];

// 定义主路由，包含需要嵌套到主布局中的页面
const mainRoutes = {
  path: '/', // 根路径
  component: _import('main'), // 主布局组件
  name: 'main', // 路由名称
  redirect: { name: 'home' }, // 默认重定向到'home'路由
  meta: { title: '主入口整体布局' }, // 设置元数据
  children: [ // 子路由
    { path: '/home', component: _import('common/home'), name: 'home', meta: { title: '首页' } }, // 首页
    { path: '/theme', component: _import('common/theme'), name: 'theme', meta: { title: '主题' } }, // 主题页面
    { path: '/demo-echarts', component: _import('demo/echarts'), name: 'demo-echarts', meta: { title: 'demo-echarts', isTab: true } }, // Echarts示例页面，通过tab展示
    { path: '/demo-ueditor', component: _import('demo/ueditor'), name: 'demo-ueditor', meta: { title: 'demo-ueditor', isTab: true } } // UEditor示例页面，通过tab展示
  ],
  beforeEnter (to, from, next) { // 路由守卫，用于在进入此路由之前进行一些检查
    let token = Vue.cookie.get('token'); // 从cookie获取token
    if (!token || !/\S/.test(token)) { // 如果没有token或token为空
      clearLoginInfo(); // 清除登录信息
      next({ name: 'login' }); // 重定向到登录页面
    }
    next(); // 继续导航
  }
};

// 创建VueRouter实例
const router = new Router({
  mode: 'hash', // 路由模式，这里使用hash模式
  scrollBehavior: () => ({ y: 0 }), // 滚动行为，每次切换路由时滚动条回到顶部
  isAddDynamicMenuRoutes: false, // 是否已经添加了动态路由
  routes: globalRoutes.concat(mainRoutes) // 将全局路由和主路由合并
});

// 全局前置守卫，用于处理动态路由
router.beforeEach((to, from, next) => {
  if (router.options.isAddDynamicMenuRoutes || fnCurrentRouteType(to, globalRoutes) === 'global') {
    // 如果已经添加了动态路由或者当前访问的是全局路由，则直接放行
    next();
  } else {
    // 发起请求获取菜单列表
    http({
      url: http.adornUrl('/sys/menu/nav'),
      method: 'get',
      params: http.adornParams()
    }).then(({data}) => {
      if (data && data.code === 0) { // 请求成功
        fnAddDynamicMenuRoutes(data.menuList); // 添加动态路由
        router.options.isAddDynamicMenuRoutes = true; // 标记已添加动态路由
        sessionStorage.setItem('menuList', JSON.stringify(data.menuList || '[]')); // 保存菜单列表到sessionStorage
        sessionStorage.setItem('permissions', JSON.stringify(data.permissions || '[]')); // 保存权限列表到sessionStorage
        next({ ...to, replace: true }); // 重新导航到目标路由
      } else {
        sessionStorage.setItem('menuList', '[]'); // 请求失败，清空菜单列表
        sessionStorage.setItem('permissions', '[]'); // 清空权限列表
        next(); // 放行
      }
    }).catch((e) => {
      console.log(`%c${e} 请求菜单列表和权限失败，跳转至登录页！！`, 'color:blue'); // 打印错误信息
      router.push({ name: 'login' }); // 跳转到登录页面
    });
  }
});

/**
 * 判断当前路由类型, global: 全局路由, main: 主入口路由
 * @param {*} route 当前路由
 */
function fnCurrentRouteType (route, globalRoutes = []) {
  var temp = [];
  for (var i = 0; i < globalRoutes.length; i++) {
    if (route.path === globalRoutes[i].path) {
      return 'global'; // 如果匹配到全局路由，返回'global'
    } else if (globalRoutes[i].children && globalRoutes[i].children.length >= 1) {
      temp = temp.concat(globalRoutes[i].children); // 如果有子路由，将子路由加入临时数组
    }
  }
  return temp.length >= 1 ? fnCurrentRouteType(route, temp) : 'main'; // 递归查找子路由
}

/**
 * 添加动态(菜单)路由
 * @param {*} menuList 菜单列表
 * @param {*} routes 递归创建的动态(菜单)路由
 */
function fnAddDynamicMenuRoutes (menuList = [], routes = []) {
  var temp = [];
  for (var i = 0; i < menuList.length; i++) {
    if (menuList[i].list && menuList[i].list.length >= 1) {
      temp = temp.concat(menuList[i].list); // 如果有子菜单，将子菜单加入临时数组
    } else if (menuList[i].url && /\S/.test(menuList[i].url)) { // 如果存在URL且非空白
      menuList[i].url = menuList[i].url.replace(/^\//, ''); // 移除URL最前面的斜杠
      var route = {
        path: menuList[i].url.replace('/', '-'), // 将URL转换为路由路径
        component: null, // 组件暂时设为null
        name: menuList[i].url.replace('/', '-'), // 路由名称
        meta: { // 元数据
          menuId: menuList[i].menuId, // 菜单ID
          title: menuList[i].name, // 菜单标题
          isDynamic: true, // 标记为动态路由
          isTab: true, // 是否通过tab展示
          iframeUrl: '' // iframe URL
        }
      };
      if (isURL(menuList[i].url)) { // 如果URL是以http(s)开头
        route['path'] = `i-${menuList[i].menuId}`; // 设置特殊路径
        route['name'] = `i-${menuList[i].menuId}`; // 设置特殊名称
        route['meta']['iframeUrl'] = menuList[i].url; // 设置iframe URL
      } else {
        try {
          route['component'] = _import(`modules/${menuList[i].url}`) || null; // 动态导入组件
        } catch (e) {}
      }
      routes.push(route); // 将路由添加到routes数组
    }
  }
  if (temp.length >= 1) {
    fnAddDynamicMenuRoutes(temp, routes); // 递归处理子菜单
  } else {
    mainRoutes.name = 'main-dynamic'; // 修改主路由名称
    mainRoutes.children = routes; // 替换主路由的子路由
    router.addRoutes([ // 添加动态路由
      mainRoutes,
      { path: '*', redirect: { name: '404' } } // 404页面路由
    ]);
    sessionStorage.setItem('dynamicMenuRoutes', JSON.stringify(mainRoutes.children || '[]')); // 保存动态路由到sessionStorage
    console.log('\n');
    console.log('%c!<-------------------- 动态(菜单)路由 s -------------------->', 'color:blue');
    console.log(mainRoutes.children);
    console.log('%c!<-------------------- 动态(菜单)路由 e -------------------->', 'color:blue');
  }
}

export default router; // 导出路由配置